package org.linlinjava.litemall.mechanismadmin.web;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.core.notify.NotifyService;
import org.linlinjava.litemall.core.notify.NotifyType;
import org.linlinjava.litemall.core.systemConfig.GetRegionService;
import org.linlinjava.litemall.core.util.CharUtil;
import org.linlinjava.litemall.core.util.LitemallMechanismToVo;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.util.bcrypt.BCryptPasswordEncoder;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.mechanismadmin.annotation.LoginAdmin;
import org.linlinjava.litemall.mechanismadmin.dao.UpdatePassword;
import org.linlinjava.litemall.mechanismadmin.service.CaptchaCodeManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/mechanismadmin/mechanism")
public class MechanismLitemallMechanismController extends GetRegionService {
	private final Log logger = LogFactory.getLog(MechanismLitemallMechanismController.class);

	private LitemallMechanismService mechanismService;

	private LitemallMechanismUserService mechanismUserService;

	private LitemallConfigService configService;

	private PlatformTransactionManager txManager;

	private LitemallUserService userService;

	private LitemallWalletRecordService walletRecordService;

	private LitemallMechanismToVo litemallMechanismToVo;

	private LitemallProxyService proxyService;

	private NotifyService notifyService;

	public MechanismLitemallMechanismController(
		LitemallMechanismService mechanismService,
		LitemallMechanismUserService mechanismUserService,
		LitemallConfigService configService,
		PlatformTransactionManager txManager,
		LitemallUserService userService,
		LitemallMechanismToVo litemallMechanismToVo,
		LitemallProxyService proxyService,
		NotifyService notifyService,
		LitemallWalletRecordService walletRecordService) {
		this.mechanismService = mechanismService;
		this.mechanismUserService = mechanismUserService;
		this.configService = configService;
		this.txManager = txManager;
		this.userService = userService;
		this.walletRecordService = walletRecordService;
		this.litemallMechanismToVo = litemallMechanismToVo;
		this.proxyService = proxyService;
		this.notifyService = notifyService;
	}

	@PostMapping("updateproxy")
	public Object updateproxy(@RequestBody LitemallMechanism mechanism) {
		mechanism.setUpdateTime(LocalDateTime.now());
		Map<String, Object> data = new HashMap<>();
		DefaultTransactionDefinition def = new DefaultTransactionDefinition();
		def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
		TransactionStatus status = txManager.getTransaction(def);
		try {
			mechanismService.updateById(mechanism);
			data.put("message", "ok");
		}
		catch (Exception e) {
			txManager.rollback(status);
			logger.error("系统内部错误", e);
			data.put("message", "default");
		}
		txManager.commit(status);
		return ResponseUtil.ok(data);
	}

	/**
	 * 发送验证码
	 */
	@GetMapping("/sendConfirmCode")
	public Object sendConfirmCode(String mobile){
		String code = CharUtil.getRandomNum(6);
		String params = new String("{\"code\":\"" + code + "\"}");
		new Thread(()->notifyService.notifySmsTemplateSync(mobile, NotifyType.CAPTCHA, params)).start();
		boolean successful = CaptchaCodeManager.addToCache(mobile, code);
		return successful ? ResponseUtil.ok() : ResponseUtil.badArgument();
	}

	/**
	 * 修改机构登录密码
	 */
	@PostMapping("/updatePassword")
	public Object updatePassword(@RequestBody UpdatePassword ad){
		//判断验证码是否正确
		String cacheCode = CaptchaCodeManager.getCachedCaptcha(ad.getMobile());
		if (cacheCode == null || cacheCode.isEmpty() || !cacheCode.equals(ad.getSecurityCode())) {
			return ResponseUtil.fail(403, "验证码错误");
		}
		//获取手机绑定的用户
		LitemallMechanism litemallMechanism = mechanismService.queryByMobile(ad.getMobile());
		if(litemallMechanism==null){
			return ResponseUtil.fail(403,"机构用户不存在，请核实手机号");
		}
		LitemallMechanismUser litemallMechanismUser = mechanismUserService.queryByMechanismsId(litemallMechanism.getId());
        //更新密码
		String rawPassword = ad.getPassword();
		if (rawPassword != null && !rawPassword.equals("")) {
			BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
			String encodedPassword = encoder.encode(rawPassword);
			litemallMechanismUser.setPassword(encodedPassword);
		}
		mechanismUserService.update(litemallMechanismUser);
		return ResponseUtil.ok();
	}

	/**
	 * 获得机构等级
	 */
	@GetMapping("/getLevel")
	public Object getLevel(@LoginAdmin Integer adminId, Integer mid){
		if (adminId == null) {
			return ResponseUtil.unlogin();
		}
		Map<String, Object> data = new HashMap<>();
		LitemallMechanism mechanism = mechanismService.findById(mid);
		if (mechanism != null || mechanism.getLevel() != null) {
			ProxyIntroduce proxy = proxyService.findById((int)mechanism.getLevel());
			if(proxy != null) {
				data.put("Proxy",proxy);
			} else {
				data.put("Proxy","");
			}
		} else {
			data.put("Proxy","");
		}
		return ResponseUtil.ok(data);
	}


	private Map<String, Object> toVo(LitemallMechanism mdList) {
		List<LitemallRegion> regionList = getLitemallRegions();
		Map<String, Object> addressVo = new HashMap<>();
		String province = "";
		String city = "";
		String area = "";
		addressVo.put("id", mdList.getId());
		addressVo.put("name", mdList.getName());
		addressVo.put("nickName", mdList.getNickName());
		addressVo.put("mechanismType", mdList.getMechanismType());
		if (mdList.getProvinceId() != null) {
			addressVo.put("provinceId", mdList.getProvinceId());
			province = regionList.stream().filter(region -> region.getId().equals(mdList.getProvinceId())).findAny().orElse(null).getName();
		}
		if (mdList.getCityId() != null) {
			addressVo.put("cityId", mdList.getCityId());
			city = regionList.stream().filter(region -> region.getId().equals(mdList.getCityId())).findAny().orElse(null).getName();
		}
		if (mdList.getAreaId() != null) {
			addressVo.put("areaId", mdList.getAreaId());
			area = regionList.stream().filter(region -> region.getId().equals(mdList.getAreaId())).findAny().orElse(null).getName();
		}
		if (mdList.getAddress() != null) {
			addressVo.put("address", mdList.getAddress());
		}
		addressVo.put("legalPerson", mdList.getLegalPerson());
		addressVo.put("telephone", mdList.getTelephone());
		addressVo.put("startTime", mdList.getStartTime());
		addressVo.put("endTime", mdList.getEndTime());
		addressVo.put("qualifications", mdList.getQualifications());
		addressVo.put("integralAmountAll", mdList.getIntegralAmountAll());
		addressVo.put("integralAmountUsed", mdList.getIntegralAmountUsed());
		addressVo.put("updateTime", mdList.getUpdateTime());
		addressVo.put("deleted", mdList.getDeleted());
		addressVo.put("province", province);
		addressVo.put("city", city);
		addressVo.put("area", area);
		addressVo.put("longitude", mdList.getLongitude());
		addressVo.put("latitude", mdList.getLatitude());
		addressVo.put("alpay", mdList.getAlpay());
		addressVo.put("wechat", mdList.getWechat());
		return addressVo;
	}

	@GetMapping("/list")
	public Object list(
		@LoginAdmin Integer adminId, Integer queryId) {
		if (adminId == null) {
			return ResponseUtil.unlogin();
		}
		LitemallMechanism mdList = mechanismService.findById(queryId);

		LitemallMechanismUser msuList = mechanismUserService.queryByMechanismId(queryId);

		Map<String, Object> addressVo = litemallMechanismToVo.toVo(mdList);

		Map<String, Object> data = new HashMap<>();
		data.put("mdList", addressVo);
		data.put("balance", msuList.getBalance());

		return ResponseUtil.ok(data);
	}

	@GetMapping("/queryCheckMeg")
	public Object queryCheckMeg(
		@LoginAdmin Integer adminId, String telephone) {
		List<LitemallMechanism> adList = mechanismService.queryCheckMeg(telephone);
		Map<String, Object> data = new HashMap<>();
		data.put("items", adList);
		return ResponseUtil.ok(data);
	}

	@GetMapping("/queryMechanismMeg")
	public Object queryMechanismMeg(
		@LoginAdmin Integer adminId, Integer mid) {
		LitemallMechanism mechanism = mechanismService.findById(mid);
		Map<String, Object> data = new HashMap<>();
		data.put("mechanism", mechanism);
		return ResponseUtil.ok(data);
	}

	@GetMapping("/goNoCheck")
	public Object goNoCheck(@LoginAdmin Integer adminId, Integer id) {
		LitemallMechanism mechanism = new LitemallMechanism();
		mechanism.setCheckStatus((byte)4);
		mechanism.setId(id);
		DefaultTransactionDefinition def = new DefaultTransactionDefinition();
		def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
		TransactionStatus status = txManager.getTransaction(def);
		try {
			mechanismService.updateById(mechanism);
		}
		catch (Exception e) {
			txManager.rollback(status);
			logger.error("系统内部错误", e);
		}
		txManager.commit(status);
		return ResponseUtil.ok();
	}

	@GetMapping("/listLevel")
	public Object list(@LoginAdmin Integer adminId) {
		Map<String, Object> data = new HashMap<>();
		List<ProxyIntroduce> ListProxy = proxyService.queryAll();

		List<Map<String, Object>> brandList = new ArrayList<>(ListProxy.size());
		for (ProxyIntroduce brand : ListProxy) {
			Map<String, Object> b = new HashMap<>(2);
			b.put("value", brand.getId());
			b.put("label", brand.getName());
			brandList.add(b);
		}
		data.put("ListProxy", ListProxy);
		data.put("brandList", brandList);

		return ResponseUtil.ok(data);
	}

	@GetMapping("/timewarn")
	public Object timewarn(@LoginAdmin Integer adminId) {
		if (adminId == null) {
			return ResponseUtil.unlogin();
		}
		Map<String, Object> data = new HashMap<>();
		LitemallMechanismUser litemallMechanismUser = mechanismUserService.findById(adminId);
		LitemallMechanism mechanism = mechanismService.findById(litemallMechanismUser.getMechanismId());
		if (mechanism.getEndTime() != null && mechanism.getCheckStatus() != null) {
			long days = mechanism.getEndTime().toLocalDate().toEpochDay() - LocalDateTime.now().toLocalDate().toEpochDay();
			data.put("checkStatus",mechanism.getCheckStatus());
			data.put("warnDays", days);
			String alpay = mechanism.getAlpay();
			data.put("alpay", alpay);
		} else {
			data.put("checkStaus","");
			data.put("warnDays", "");
			data.put("alpay", "");
		}
		return ResponseUtil.ok(data);
	}

	@PostMapping("/create")
	public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallMechanism ad) {
		if (adminId == null) {
			return ResponseUtil.unlogin();
		}
		ad.setUpdateTime(LocalDateTime.now());

		mechanismService.add(ad);
		return ResponseUtil.ok(ad);
	}

	/**
	 * 通过机构ID获取它的名称
	 *
	 * @param id
	 * @return
	 */
	@GetMapping("/merchanismName")
	public Object merchanismName(@NotNull Integer id) {
		String name = "";
		LitemallMechanism litemallMechanism = mechanismService.findById(id);
		if (litemallMechanism != null) {
			name = litemallMechanism.getName();
		}
		return ResponseUtil.ok(name);
	}

	@GetMapping("/read")
	public Object read(@LoginAdmin Integer adminId, Integer id) {
		if (adminId == null) {
			return ResponseUtil.unlogin();
		}

		if (id == null) {
			return ResponseUtil.badArgument();
		}

		LitemallMechanism brand = mechanismService.findById(id);
		return ResponseUtil.ok(brand);
	}

	@PostMapping("/update")
	public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallMechanism ad) {
		if (adminId == null) {
			return ResponseUtil.unlogin();
		}
		mechanismService.updateById(ad);
		return ResponseUtil.ok(ad);
	}

	@PostMapping("/delete")
	public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallMechanism ad) {
		if (adminId == null) {
			return ResponseUtil.unlogin();
		}
		mechanismService.deleteById(ad.getId());
		return ResponseUtil.ok();
	}

	@GetMapping("/listUserData")
	public Object listUserData(Integer queryId) {
		if (queryId == null) {
			return ResponseUtil.unlogin();
		}
		LitemallMechanism mdList = mechanismService.findById(queryId);
		LitemallUser userData = mechanismService.selectUser(mdList.getTelephone());
		//判断user表中是否存在
		if (userData == null) {
			return ResponseUtil.ok(userData);
		}
		return ResponseUtil.ok(userData);
	}

	@GetMapping("/updateBalance")
	public Object updateBalance(String exchangeNum, String mobile, String recordSn) {
		//传过来的recordSn去空格
		String recordSnStr = recordSn.replace(" ", "");
		//根据手机号查询User表
		LitemallUser user = mechanismService.selectUser(mobile);

		BigDecimal num = new BigDecimal(exchangeNum);
		//比较传过来的值是否比用户原有的爱币大
		if (num.compareTo(user.getBalance()) == 1) {
			return ResponseUtil.badArgumentValue();
		}
		//获取积分兑换比例
		LitemallConfig integralToANBConfig = configService.findById(10000002);
		Double integralToANBValue = Double.parseDouble(integralToANBConfig.getValue());
		//获取改变的爱币数和积分数
		BigDecimal exchangeBalance = new BigDecimal(Integer.parseInt(exchangeNum));
		BigDecimal integral = exchangeBalance.divide(new BigDecimal(integralToANBValue), 1, BigDecimal.ROUND_HALF_DOWN);
		int exchangeIntegral = integral.intValue();
		BigDecimal newBalance = user.getBalance().subtract(exchangeBalance);
		int newIntegral = user.getIntegral() + exchangeIntegral;
		//将改变后的爱币和积分值复制到user中
		user.setBalance(newBalance);
		user.setIntegral(newIntegral);

		LitemallWalletRecord walletRecord = new LitemallWalletRecord();
		//向walletRecord表中添加修改记录
		walletRecord.setModifyIntegral(exchangeIntegral);
		walletRecord.setModifyAmount(exchangeBalance.multiply(new BigDecimal(-1)));
		walletRecord.setModifyReason("用户爱币兑换积分");
		walletRecord.setUserId(user.getId());
		walletRecord.setModifyTime(LocalDateTime.now());
		walletRecord.setPayTime(LocalDateTime.now());
		walletRecord.setType(new Byte("3"));
		walletRecord.setPayType(new Byte("3"));
		walletRecord.setPayId(recordSnStr);
		walletRecord.setRecordSn(recordSnStr);

		// 开启事务管理
		DefaultTransactionDefinition def = new DefaultTransactionDefinition();
		def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
		TransactionStatus status = txManager.getTransaction(def);
		try {
			//更新修改数据
			userService.update(user);
			walletRecordService.add(walletRecord);
		}
		catch (Exception ex) {
			txManager.rollback(status);
			logger.error("兑换出错！", ex);
		}
		txManager.commit(status);
		//返回修改的结果
		return ResponseUtil.ok(user);
	}
}
